import { OnInit, OnChanges, OnDestroy, Component, ChangeDetectionStrategy, ViewEncapsulation, Input, TemplateRef, NgZone, ViewChild, ElementRef } from '@angular/core';
import { InputNumber, InputBoolean } from 'ng-zorro-antd';
import { Lbchart } from '@shared';
import { Subscription } from 'rxjs';
/**
 * 基础仪表盘
 */
@Component({
  selector: 'lb-basic-gauge',
  template: `
    <div #basicgauge></div>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush, // 检测改为按需，即不自动刷新
})
export class LbBasicGaugeComponent implements OnInit, OnChanges, OnDestroy,Lbchart {
  private chart: any;
  private resize$: Subscription;
  @ViewChild('basicgauge', { static: true }) private node: ElementRef;
  @Input() padding: Array<number | string> | string = 'auto';
  @Input() @InputNumber() delay = 0;
  @Input() color:string[] = null;
  @Input() colorFiled='name';
  @Input() position: any

  @Input() title: string
  // @Input() position: {x: string, y: string} = { x: '1', y: 'value' }
  @Input() transpercent: boolean = false

  @Input() data: any []

  @Input() height: number;

  @Input() @InputBoolean() centertitleshow = false; // 是否显示内部标题
  @Input() centertitletext; // 内部标题
  @Input() @InputNumber() centertitletextsize
  @Input() @InputBoolean() centertitleshowtotal = false;
  @Input() @InputNumber() centertitletotalsize

  @Input() arclineradius = 80
  @Input() arclinewidth = 16

  constructor(private ngZone: NgZone) { }

  install() {
    this.render()
  }

  render() {
    const { node, padding } = this;
    const container = node.nativeElement as HTMLElement;

    const Shape = G2.Shape;
// 自定义Shape 部分
Shape.registerShape('point', 'pointer', {
  drawShape(cfg, group) {
    const center = this.parsePoint({ // 获取极坐标系下画布中心点
      x: 0,
      y: 0
    });
    // 绘制指针
    group.addShape('line', {
      attrs: {
        x1: center.x,
        y1: center.y,
        x2: cfg.x,
        y2: cfg.y,
        stroke: cfg.color,
        lineWidth: 5,
        lineCap: 'round'
      }
    });
    return group.addShape('circle', {
      attrs: {
        x: center.x,
        y: center.y,
        r: 9.75,
        stroke: cfg.color,
        lineWidth: 4.5,
        fill: '#fff'
      }
    });
  }
});

    const chart = (this.chart = new G2.Chart({
      container,
      forceFit: true,  // 图表的宽度自适应开关
      height: this.getHeight(),
      padding,
    }));

    const data = this.data
    // Step 2: 载入数据源
    chart.source(data);
    // Step 3：创建图形语法，绘制柱状图，由 genre 和 sold 两个属性决定图形位置，genre 映射至 x 轴，sold 映射至 y 轴
    chart.coord('polar', {
      startAngle: -9 / 8 * Math.PI,
      endAngle: 1 / 8 * Math.PI,
      radius: 0.8
    });
    chart.scale(this.position.y, {
      min: 0,
      max: 100,
      tickInterval: 10,
      nice: true
    });
    chart.legend(false);
    chart.axis(this.position.x, false);
    chart.axis(this.position.y, {
      zIndex: 2,
      line: null,
      label: {
        offset: -1,
        textStyle: {
          fontSize: 18,
          textAlign: 'center',
          textBaseline: 'middle'
        }
      },
      subTickCount: 4,
      subTickLine: {
        length: 0,
        stroke: '#fff',
        strokeOpacity: 1
      },
      tickLine: {
        length: 0,
        stroke: '#000',
        strokeOpacity: 1
      },
      grid: null
    });

    chart
      .point()
      .position(`${this.position.y}*${this.position.x}`)
      .shape('pointer')
      .color('#1890FF')
      .active(false);
   
      const self = this
    // 绘制仪表盘背景
    chart.guide().arc({
      zIndex: 0,
      top: false,
      start: (xScales, yScales) => [ 0, self.arclineradius / 100 ],
      end: (xScales, yScales) => [ 100, self.arclineradius / 100 ],
      style: { // 底灰色
        stroke: '#CBCBCB',
        lineWidth: this.arclinewidth
      }
    });
    // 绘制指标
    chart.guide().arc({
      zIndex: 1,
      start(xScales, yScales) {
        return  [ 0, self.arclineradius / 100 ]
      },
      end(xScales, yScales) {
        return  [ data[0][self.position.y], self.arclineradius / 100]
      },
      style: {
          stroke: '#1890FF',
          lineWidth: this.arclinewidth
        }
    });

    // 中心标题
    chart.guide().html({
      // position: [ '50%', '50%' ],
      position: (xScale, yScale) => {
        return this.centertitleshow ? ['50%', '90%'] : null;
      },
      // html: '<div style="color:#8c8c8c;font-size: 14px;text-align: center;width: 10em;">'+this.centertitletext+'<br><span style="color:#8c8c8c;font-size:20px">200</span></div>',
      html: val => {
        return (
          `<div style="color:#8c8c8c;font-size: ${this.centertitletextsize}px;text-align: center;width: 10em;">${this.centertitletext}<br><span style="color:#8c8c8c;font-size:${this.centertitletotalsize}px">${this.centertitleshowtotal ? data[0][this.position.y] + '%'  : ''}</span></div>`
        )
      },
      alignX: 'middle',
      alignY: 'middle',
    });

    // // 绘制指标数字
    // chart.guide().html({
    //   position: [ '50%', '100%' ],
    //   html: '<div style="width: 300px;text-align: center;">'
    //     + `${this.centertitleshow?('<p style="font-size: '+(this.centertitletextsize?this.centertitletextsize:20)+'px; color: #545454;margin: 0;">'+(this.centertitletext?this.centertitletext:'')+'</p>'):''}`
    //     + (this.centertitleshowtotal?('<p style="font-size: '+this.centertitletotalsize?this.centertitletotalsize:30+'px;color: #545454;margin: 0;">' + data[0][this.position.y] + '%</p>'): '')
    //     + '</div>'
    // });

    // Step 4: 渲染图表
    chart.render();
  }

   attachChart() {
    const { chart, padding, data, color } = this;
    if (!chart || !data || data.length <= 0) return;
    const height = this.getHeight();
    if (chart.get('height') !== height) {
      chart.changeHeight(height);
    }

 
     // color
    //  chart.get('geoms')[0].color(this.colorFiled,this.color);
     chart.set('padding', padding);
     chart.changeData(data);
  }

  destroy(){
    if (this.resize$) {
      this.resize$.unsubscribe();
    }
    if (this.chart) {
      this.ngZone.runOutsideAngular(() => this.chart.destroy());
    }
  }

  /**
   * 报表高度
   * 存在报表头，则需要减掉报表头的高度
   */
   getHeight() {
     return this.height
    // return this.title ? (this.height - TITLE_HEIGHT) : this.height;
  }


  ngOnInit(): void {
    if(this.position&&this.data.length>0){
      this.ngZone.runOutsideAngular(() => setTimeout(() => this.install(), this.delay));
    }
   
  }  
  
  ngOnChanges(changes: import("@angular/core").SimpleChanges): void {
    this.ngZone.runOutsideAngular(() => this.attachChart());
  }
  ngOnDestroy(): void {
    this.destroy();
  }
}